using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityUtilities;

public class InputManagement : MonoBehaviour
{
    /// <summary>
    /// 定义玩家所能按下的按键
    /// </summary>
    public enum keyBind
    {
        MOVE_UP,
        MOVE_DOWN,
        MOVE_LEFT,
        MOVE_RIGHT,
        SKILL_KEY_1,
        SKILL_KEY_2,
        SKILL_KEY_3,
        SKILL_KEY_4,
        SKILL_KEY_5,
        SKILL_KEY_6,
    }
    public enum playerID
    {
        PLAYER_1,
        PLAYER_2
    }
    private KeyCode up, down, left, right, key1, key2, key3, key4, key5, key6;
    /// <summary>
    /// 按键组合list
    /// </summary>
    public List<InputCombo> combos;
    /// <summary>
    /// 玩家号,1或者2
    /// </summary>
    public playerID player;
    /// <summary>
    /// 按键组合种下一个按键按下的最长时间间隔,超过这个时间则整个按键组合失效,单位ms
    /// </summary>
    public float inputInterval;
    public skillControl skillControl;
    /// <summary>
    /// 按下的按键队列
    /// </summary>
    private Queue<keyBind> keyQueue;

    private Countdown countDown;
    private void Awake()
    {
        countDown = new Countdown(false, inputInterval / 1000.0f);
        //分配不同玩家的按键定义
        if (player == playerID.PLAYER_1)
        {
            up = KeyCode.W;
            down = KeyCode.S;
            left = KeyCode.A;
            right = KeyCode.D;
            key1 = KeyCode.J;
            key2 = KeyCode.K;
            key3 = KeyCode.L;
            key4 = KeyCode.U;
            key5 = KeyCode.I;
            key6 = KeyCode.O;

        }
        else
        {
            up = KeyCode.UpArrow;
            down = KeyCode.DownArrow;
            left = KeyCode.LeftArrow;
            right = KeyCode.RightArrow;
            key1 = KeyCode.Keypad1;
            key2 = KeyCode.Keypad2;
            key3 = KeyCode.Keypad3;
            key4 = KeyCode.Keypad4;
            key5 = KeyCode.Keypad5;
            key6 = KeyCode.Keypad6;

        }
        keyQueue = new Queue<keyBind>(10);
    }
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (countDown.Progress() && keyQueue.Count != 0)
        {
            keyQueue.Clear();
        }
        inputKey();

    }
    /// <summary>
    /// 检测是否有按键组合被激活
    /// </summary>
    private void process()
    {
        //不处理单个按键
        if (keyQueue.Count < 2) { return; }
        for (int i = 0; i < combos.Count; i++)
        {

            keyBind[] combo = combos[i].combo.ToArray();
            int comboLength = combo.Length;
            //如果当前按键队列长度小于按键组合长度,直接跳过本次循环
            if (keyQueue.Count < comboLength)
            {
                continue;
            }

            //第一个元素是队头，最后一个元素是队尾
            keyBind[] input = new keyBind[comboLength];

            Array.ConstrainedCopy(keyQueue.ToArray(), keyQueue.ToArray().Length - comboLength, input, 0, comboLength);
            //处理有顺序组合按键
            if (combos[i].comboType == InputCombo.COMBO_TYPE.COMBO_TYPE_ORDERED)
            {
                if (Enumerable.SequenceEqual(input, combo))
                {
                    skillControl.playSkill(combos[i].skill);
                    keyQueue.Clear();

                }

            }
            //处理无序组合按键
            else
            {
                bool success = true;
                for (int l = 0; l < comboLength; l++)
                {
                    if (!input.Contains(combo[l]))
                    {
                        success = false;
                    }

                }
                if (success)
                {
                    skillControl.playSkill(combos[i].skill);
                    keyQueue.Clear();
                }

            }
        }

    }
    private void processInput(Action next)
    {
        //如果上一个按键到这个按键之间的间隔超过了最大间隔时间,就重置队列
        //那么按键组合就无效
        if (countDown.ReachedZero && keyQueue.Count > 1)
        {
            keyQueue.Clear();
        }
        //如果没有超过最大间隔,就将按键加入队列,并重新启动计时器
        //并判断队列中是否存在成型的按键组合
        else
        {
            next();
            //Debug.Log(keyQueue.ToString());
            process();
            countDown.Reset();
        }

    }
    /// <summary>
    /// 按键输入入队
    /// </summary>
    private void inputKey()
    {
        if (Input.GetKeyDown(up))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.MOVE_UP);
            });
        }
        if (Input.GetKeyDown(down))
        {
            processInput(() =>
            {
                keyQueue.Enqueue(keyBind.MOVE_DOWN);
            });

        }

        if (Input.GetKeyDown(left))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.MOVE_LEFT);
            });

        }

        if (Input.GetKeyDown(right))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.MOVE_RIGHT);
            });

        }

        if (Input.GetKeyDown(key1))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.SKILL_KEY_1);
            });

        }

        if (Input.GetKeyDown(key2))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.SKILL_KEY_2);
            });

        }

        if (Input.GetKeyDown(key3))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.SKILL_KEY_3);
            });

        }

        if (Input.GetKeyDown(key4))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.SKILL_KEY_4);
            });

        }

        if (Input.GetKeyDown(key5))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.SKILL_KEY_5);
            });

        }

        if (Input.GetKeyDown(key6))
        {
            processInput(() =>
            {

                keyQueue.Enqueue(keyBind.SKILL_KEY_6);
            });

        }
    }
}
